#include "StepByStep.h"

#define DOMAINLAW


// Domain Information
char        Name[DOMAIN_NAME+1];
StringList  *Require = NULL;
int         NumConstant;       // Number of Constants
TypedList   *Constants = NULL;
TypedList   *Type = NULL;
int         NumPred;           // Number of Predications
PredList    *Predication = NULL;
int         NumAct;            // Number of Actions
ActionList  *Action = NULL;
DomainAxiom *Axioms = NULL;
SafetyStru  *Safe = NULL;       // Safety of Domain

PKTree *PK, *nPK;

// Lists Of All Plan Domain
DomainLaw *Law0, *Law1, *Law3;
DomainLaw *TLaw0, *TLaw1, *TLaw3;
int  NumLaw0, NumLaw1, NumLaw3;

Bool Typing, Axiom, Exist, Universal, Safety;
// End of Domain

// Fact Information
char      ProbName[PROBLEM_NAME+1], DomName[DOMAIN_NAME+1];
int       NumObject;
TypedList *Objects;
PENode    *Init;
int       Serial, Parallel;
StateOfPlan *State;
int       NumTarget;
PENode    *Goal;
// End of Fact

int  MaxStep, ErrorNo;

#ifdef GAM
int GamNo;
FoInf *PreFoInf;
FoInf *nPreFoInf;
#endif

Bool DispLaw;
char ErrorMsg[ERR_LENGTH+1];

int  lineno, gbracket_count;
FILE *Output;

char *Types[] = { "Atom", "Not", "And", "Forall", "Exist", "Or", "When" };
char Path[PATH+1], DMFile[FILENAME+1], FTFile[FILENAME+1];

void Usage()
{
	printf("\nUsage: [-p Path] [-o DName] [-f FName] [-L] [-S Step] [-O Output]\n\n");
	printf("Options Descriptions:\n");
	printf("-p <str>   Path for Domain and Fact File (Default - %s)\n", Path);
	printf("-o <str>   File Name of Domain (Default - %s)\n", DMFile);
	printf("-f <str>   File Name of Problem (Default - %s)\n", FTFile);
	printf("========================================================\n");
	printf("-L         Display Domain Laws\n");
#ifdef GAM
	printf("-g <num>    goal agenda manager level\n");
	printf("     0    : no agenda computed ( preset )\n" );
	printf("     1    : compute agenda, plan for it\n" );
	printf("     2    : only compute agenda, no plan\n" );
#endif
	printf("-S <Num>   Max Number of Steps of Plan (Default - %d)\n", MaxStep);
	printf("-O <str>   Output File Name (Default - Screen)\n\n");

	exit(ERROR);
}

int main(int argc, char *argv[])
{
	//struct tms Start, EndOfPlan;
  struct timeval Start, EndOfPlan;
#ifdef DOMAINLAW
	//struct tms EndOfLaw;
  struct timeval EndOfLaw;
#endif
	char   ch1, File[PATH+FILENAME+1];
	int    i;

	MaxStep = 10;
	GamNo = 2;
	ErrorNo = NOFOUND;
	DispLaw = FALSE;

	strcpy(Path, "./");
	strcpy(DMFile, "domain.pddl");
	strcpy(FTFile, "problem.pddl");

	Output = stdout;

	i = 1;
	while (i < argc) {
		ch1 = argv[i][0];
		if (ch1 != '-') Usage();

		ch1 = argv[i++][1];
		switch (ch1) {
	   case 'p':
		   strcpy(Path, argv[i]);
		   break;
	   case 'o':
		   strcpy(DMFile, argv[i]);
		   break;
	   case 'f':
		   strcpy(FTFile, argv[i]);
		   break;
	   case 'L':
		   DispLaw = TRUE;
		   i--;
		   break;
	   case 'S':
		   MaxStep = atoi(argv[i]);
		   break;
#ifdef GAM
	   case 'g':
		   GamNo = atoi(argv[i]);
		   break;
#endif
	   case 'O':
		   Output = fopen(argv[i], "a+");
		   if (Output == NULL) {
			   printf("-O <str>   Output File Name (Default - Screen)\n\n");
			   Output = stdout;
		   }
		   break;
	   case 'h':
	   case '?':
		   i--;
		   Usage();
		   break;
		}
		i++;
	}

	strcpy(File, Path); strcat(File, DMFile);

	//times(&Start);
  gettimeofday(&Start, NULL);

	GetDomainInfo(File);                  // In ddomain.c
	TranDomainDefine();                   // In ddomain.c
	GetDomainKnowledgeTree();             // In tree.c

	GetDomainLaw();                       // In law.c

#ifdef DOMAINLAW
	fprintf(Output, "Concomitancy/Cond-Concomitancy:%3d\n", NumLaw0);
	fprintf(Output, "Direct and Indirect Obstructive:%3d\n", NumLaw1);
	fprintf(Output, "Absolute Obstructive:%3d\n", NumLaw3);

	//times(&EndOfLaw);
  gettimeofday(&EndOfLaw, NULL);
	//fprintf(Output, "Domain Law: User CPU - %.2fs, System CPU - %.2fs\n",
	 //               (float)(EndOfLaw.tms_utime - Start.tms_utime)/100.0,
	  //              (float)(EndOfLaw.tms_stime - Start.tms_stime)/100.0);
  fprintf(Output, "Domain Law: %.2f msecond\n",
	                (float)(EndOfLaw.tv_sec - Start.tv_sec)*1000.0+(float)(EndOfLaw.tv_usec - Start.tv_usec)/1000.0);
#endif

	strcpy(File, Path); strcat(File, FTFile);
	GetFactInfo(File);                    // In ffact.c
	TransFactInfo();                      // In ffact.c

	if (Goal!=NULL && Goal->Pred!=NULL) StepByStep();       // In plan.c
	else fprintf(Output, "\nThe target state is EMPTY.\n\n");

	FreeMemoryOfGoalState();              // In memory.c
	FreeDomainMemory();                   // In memory.c

	//times(&EndOfPlan);
  gettimeofday(&EndOfPlan, NULL);
	//fprintf(Output, "\nAll Time: User CPU - %.2fs, System CPU - %.2fs\n",
	//                (float)(EndOfPlan.tms_utime - Start.tms_utime)/100.0,
	//                (float)(EndOfPlan.tms_stime - Start.tms_stime)/100.0);
  fprintf(Output, "\nAll Time: %.2f msecond\n",
	                (float)(EndOfPlan.tv_sec - Start.tv_sec)*1000.0+(float)(EndOfPlan.tv_usec - Start.tv_usec)/1000.0);
  
	fprintf(Output, "Path: %s\nDomain: %s, Problem: %s\n\n", Path, DMFile, FTFile);

	fclose(Output);
	return TRUE;
}
